"""
事件分发服务
统一管理和分发系统事件
"""

import asyncio
import time
from typing import Dict, Any, List, Callable, Optional
from enum import Enum

from ..logger import logger


class EventType(str, Enum):
    """事件类型枚举"""
    MODEL_DISCOVERED = "model_discovered"
    MODEL_UPDATED = "model_updated"
    MODEL_DELETED = "model_deleted"
    MODEL_DISPATCH_STARTED = "model_dispatch_started"
    MODEL_DISPATCHED = "model_dispatched"
    SUBSCRIPTION_CREATED = "subscription_created"
    SUBSCRIPTION_UPDATED = "subscription_updated"
    SUBSCRIPTION_DELETED = "subscription_deleted"
    SERVER_ONLINE = "server_online"
    SERVER_OFFLINE = "server_offline"
    SERVER_ERROR = "server_error"
    SYSTEM_STATUS = "system_status"
    CLIENT_CONNECTED = "client_connected"
    CLIENT_DISCONNECTED = "client_disconnected"


class Event:
    """事件对象"""
    
    def __init__(
        self,
        event_type: EventType,
        data: Dict[str, Any],
        source: str = "system",
        timestamp: Optional[float] = None
    ):
        self.event_type = event_type
        self.data = data
        self.source = source
        self.timestamp = timestamp or time.time()
        self.id = self._generate_event_id()
        
    def _generate_event_id(self) -> str:
        """生成事件ID"""
        from ..utils import generate_short_id
        return f"{self.event_type}_{generate_short_id()}"
        
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典"""
        return {
            "id": self.id,
            "type": self.event_type,
            "data": self.data,
            "source": self.source,
            "timestamp": self.timestamp
        }


class EventHandler:
    """事件处理器基类"""
    
    def __init__(self, name: str, event_types: List[EventType]):
        self.name = name
        self.event_types = event_types
        
    async def handle(self, event: Event) -> bool:
        """处理事件，返回是否成功"""
        raise NotImplementedError
        
    def can_handle(self, event_type: EventType) -> bool:
        """检查是否可以处理指定类型的事件"""
        return event_type in self.event_types


class WebSocketEventHandler(EventHandler):
    """WebSocket事件处理器"""
    
    def __init__(self):
        super().__init__(
            "websocket_handler",
            list(EventType)  # 处理所有事件类型
        )
        
    async def handle(self, event: Event) -> bool:
        """处理WebSocket事件"""
        try:
            from .notification_service import notification_service
            
            message = {
                "type": "event",
                "event": event.to_dict()
            }
            
            await notification_service.send_websocket_message(message)
            return True
            
        except Exception as e:
            logger.error(f"WebSocket event handler error: {e}")
            return False


class SubscriptionEventHandler(EventHandler):
    """订阅事件处理器"""
    
    def __init__(self):
        super().__init__(
            "subscription_handler",
            [EventType.MODEL_DISCOVERED, EventType.MODEL_UPDATED]
        )
        
    async def handle(self, event: Event) -> bool:
        """处理订阅相关事件"""
        try:
            from .notification_service import notification_service
            
            # 广播到相关订阅者
            await notification_service.broadcast_event(event.to_dict())
            return True
            
        except Exception as e:
            logger.error(f"Subscription event handler error: {e}")
            return False


class LogEventHandler(EventHandler):
    """日志事件处理器"""
    
    def __init__(self):
        super().__init__(
            "log_handler",
            list(EventType)  # 记录所有事件
        )
        
    async def handle(self, event: Event) -> bool:
        """记录事件到日志"""
        try:
            logger.info(f"Event: {event.event_type} from {event.source} - {event.data}")
            return True
            
        except Exception as e:
            logger.error(f"Log event handler error: {e}")
            return False


class EventDispatcher:
    """事件分发器"""
    
    def __init__(self):
        self.handlers: List[EventHandler] = []
        self.event_queue = asyncio.Queue()
        self.is_running = False
        self.dispatch_task = None
        self.event_history: List[Event] = []
        self.max_history_size = 1000
        
    async def start(self):
        """启动事件分发器"""
        if self.is_running:
            return
            
        self.is_running = True
        
        # 注册默认处理器
        self.register_handler(WebSocketEventHandler())
        self.register_handler(SubscriptionEventHandler())
        self.register_handler(LogEventHandler())
        
        # 启动分发任务
        self.dispatch_task = asyncio.create_task(self._dispatch_loop())
        
        logger.info("Event dispatcher started")
        
    async def stop(self):
        """停止事件分发器"""
        self.is_running = False
        
        if self.dispatch_task:
            self.dispatch_task.cancel()
            try:
                await self.dispatch_task
            except asyncio.CancelledError:
                pass
                
        logger.info("Event dispatcher stopped")
        
    def register_handler(self, handler: EventHandler):
        """注册事件处理器"""
        self.handlers.append(handler)
        logger.debug(f"Registered event handler: {handler.name}")
        
    def unregister_handler(self, handler_name: str):
        """注销事件处理器"""
        self.handlers = [h for h in self.handlers if h.name != handler_name]
        logger.debug(f"Unregistered event handler: {handler_name}")
        
    async def dispatch_event(self, event: Event):
        """分发事件"""
        try:
            # 添加到队列
            await self.event_queue.put(event)
            
            # 添加到历史记录
            self._add_to_history(event)
            
        except Exception as e:
            logger.error(f"Error dispatching event: {e}")
            
    async def emit(
        self,
        event_type: EventType,
        data: Dict[str, Any],
        source: str = "system"
    ):
        """发出事件"""
        event = Event(event_type, data, source)
        await self.dispatch_event(event)
        
    async def _dispatch_loop(self):
        """事件分发循环"""
        while self.is_running:
            try:
                # 等待事件
                event = await asyncio.wait_for(self.event_queue.get(), timeout=1.0)
                
                # 分发给所有相关处理器
                tasks = []
                for handler in self.handlers:
                    if handler.can_handle(event.event_type):
                        task = asyncio.create_task(handler.handle(event))
                        tasks.append(task)
                
                # 等待所有处理器完成
                if tasks:
                    results = await asyncio.gather(*tasks, return_exceptions=True)
                    
                    # 统计处理结果
                    success_count = sum(1 for result in results if result is True)
                    total_count = len(results)
                    
                    if success_count < total_count:
                        logger.warning(
                            f"Event {event.event_type} processed by {success_count}/{total_count} handlers"
                        )
                
            except asyncio.TimeoutError:
                continue
            except asyncio.CancelledError:
                break
            except Exception as e:
                logger.error(f"Error in event dispatch loop: {e}")
                
    def _add_to_history(self, event: Event):
        """添加事件到历史记录"""
        self.event_history.append(event)
        
        # 限制历史记录大小
        if len(self.event_history) > self.max_history_size:
            self.event_history = self.event_history[-self.max_history_size:]
            
    def get_recent_events(self, limit: int = 50) -> List[Dict[str, Any]]:
        """获取最近的事件"""
        recent_events = self.event_history[-limit:]
        return [event.to_dict() for event in recent_events]
        
    def get_events_by_type(self, event_type: EventType, limit: int = 50) -> List[Dict[str, Any]]:
        """根据类型获取事件"""
        filtered_events = [
            event for event in self.event_history 
            if event.event_type == event_type
        ][-limit:]
        
        return [event.to_dict() for event in filtered_events]
        
    def get_stats(self) -> Dict[str, Any]:
        """获取统计信息"""
        # 统计各类型事件数量
        event_counts = {}
        for event in self.event_history:
            event_type = event.event_type
            event_counts[event_type] = event_counts.get(event_type, 0) + 1
            
        return {
            "total_events": len(self.event_history),
            "event_types": event_counts,
            "handlers_count": len(self.handlers),
            "queue_size": self.event_queue.qsize(),
            "is_running": self.is_running
        }


# 全局事件分发器实例
event_dispatcher = EventDispatcher()
